package org.testis.utils.middleware;

import java.util.HashMap;
import java.util.LinkedList;
import org.orm.PersistentException;
import org.orm.PersistentTransaction;
import org.testis.orm.classes.T_test_label;
import org.testis.orm.classes.T_test_labelCriteria;
import org.testis.orm.classes.T_test_labelFactory;
import org.testis.orm.classes.T_test_label_inclusion;
import org.testis.orm.classes.T_test_label_inclusionCriteria;
import org.testis.orm.classes.T_test_label_inclusionFactory;
import org.testis.orm.classes.T_test_labelpairs;
import org.testis.orm.classes.T_test_labelpairsCriteria;
import org.testis.utils.tree.LabelTreeNode;

/**
 * 
 * @author nurhat
 */
public class LabelDataHandler extends DbConnectionSupplier {

    private static HashMap<Integer, T_test_label> m_labels = new HashMap<Integer, T_test_label>();

    private HashMap labelListToMap(T_test_label[] list) {
	HashMap hm = new HashMap();
	if (list != null) {
	    for (int i = 0; i < list.length; i++) {
		T_test_label tmp = list[i];
		hm.put(tmp.getId(), tmp.getName());
	    }
	}
	// return HashMapUtils.sortHashMapByValues(hm);
	return hm;
    }

    private HashMap labelInclusionListToMap(T_test_label_inclusion[] list) {
	HashMap hm = new HashMap();
	if (list != null) {
	    for (int i = 0; i < list.length; i++) {
		T_test_label_inclusion tmp = list[i];
		hm.put(tmp.getContainee().getId(), tmp);
	    }
	}
	return HashMapUtils.sortHashMapByKeys(hm);
    }

    public HashMap getLabelsAsMap() {
	return labelListToMap(getLabelsAsArray());
    }

    public boolean removeLabel(int labelId) {
	boolean result = false;
	try {
	    PersistentTransaction t = openDBConnection().beginTransaction();
	    try {
		T_test_label obj = getLabelById(labelId);
		result = removeLabelRecursive(obj);
		t.commit();
		m_labels.remove(labelId);
	    } catch (PersistentException ex) {
		t.rollback();
	    } finally {
		closeDBConnection();
	    }
	} catch (PersistentException ex) {
	}
	return result;
    }

    private boolean removeLabelRecursive(T_test_label label)
	    throws PersistentException {
	boolean result = false;
	if (label != null) {
	    T_test_labelpairsCriteria criteria = new T_test_labelpairsCriteria();
	    criteria.labelId.eq(label.getId());
	    // delete each label pair
	    T_test_labelpairs[] pairs = criteria.listT_test_labelpairs();
	    for (int i = 0; i < pairs.length; i++) {
		pairs[i].deleteAndDissociate();
	    }

	    // delete the inclusion record if this is containee
	    T_test_label_inclusion[] containee_inclusions = label.t_test_label_inclusion1
		    .toArray();
	    for (int i = 0; i < containee_inclusions.length; i++) {
		containee_inclusions[i].deleteAndDissociate();
	    }

	    // remove each label_inclusion record and containee label
	    // recursively
	    T_test_label_inclusion[] container_inclusions = getLabelInclusions(label
		    .getId());
	    for (int i = 0; i < container_inclusions.length; i++) {
		// and remove for each containee label and delete inclusions
		T_test_label containee = container_inclusions[i].getContainee();
		// container_inclusions[i].delete();
		removeLabelRecursive(containee);
	    }
	    result = label.delete();
	}
	return result;
    }

    public T_test_label[] getLabelsAsArray() {
	T_test_label[] result = null;
	try {
	    result = T_test_labelFactory.listT_test_labelByQuery(null, null);
	} catch (PersistentException ex) {
	}
	return result;
    }

    public LinkedList<String> getLabelNames() {
	LinkedList<String> result = new LinkedList<String>();
	T_test_label[] labelList = getLabelsAsArray();
	if (labelList != null) {
	    for (int i = 0; i < labelList.length; i++) {
		result.add(labelList[i].getName());
	    }
	}
	return result;
    }

    public T_test_label_inclusion[] getLabelInclusions(int containerId) {
	T_test_label_inclusion[] inclusions = null;
	try {
	    T_test_label_inclusionCriteria inclusionCriteria = new T_test_label_inclusionCriteria();
	    inclusionCriteria.createContainerCriteria().id.eq(containerId);
	    inclusions = inclusionCriteria.listT_test_label_inclusion();
	} catch (PersistentException ex) {
	}
	return inclusions;
    }

    /*
     */
    public T_test_label_inclusion getLabelInclusionByContaineeId(int containeeId) {
	T_test_label_inclusion result = null;
	try {
	    T_test_label_inclusionCriteria inclusionCriteria = new T_test_label_inclusionCriteria();
	    inclusionCriteria.createContaineeCriteria().id.eq(containeeId);
	    T_test_label_inclusion[] inclusions = inclusionCriteria
		    .listT_test_label_inclusion();
	    if (inclusions != null) {
		result = inclusions[0];
	    }
	} catch (PersistentException ex) {
	}
	return result;
    }

    public int getNumberOfLabelInclusions(int containerId) {
	T_test_label_inclusion[] inclusions = getLabelInclusions(containerId);
	int result = 0;
	if (inclusions != null) {
	    result = inclusions.length;
	}
	return result;
    }

    public T_test_label_inclusion[] getLabelInclusions() {
	T_test_label_inclusion[] result = null;
	try {
	    result = T_test_label_inclusionFactory
		    .listT_test_label_inclusionByQuery(null, null);
	} catch (PersistentException ex) {
	}
	return result;
    }

    public HashMap getLabelInclusionsAsMap() {
	return labelInclusionListToMap(getLabelInclusions());
    }

    /*
     * public LabelTreeNode getLabelsAsTree() { LabelTreeNode root = new
     * LabelTreeNode("Labels"); T_test_label[] labels = getLabelsAsArray();
     * HashMap labelNodeMap = new HashMap(); for (int i = 0; i < labels.length;
     * i++) { T_test_label label = labels[i]; LabelTreeNode node = new
     * LabelTreeNode(label); labelNodeMap.put(label.getId(), node); }
     * 
     * for (int i = 0; i < labels.length; i++) { T_test_label label = labels[i];
     * LabelTreeNode node = (LabelTreeNode) labelNodeMap.get(label.getId()); if
     * (label.t_test_label_inclusion.size() > 0) { T_test_label_inclusion[]
     * inclusions = labels[i].t_test_label_inclusion.toArray(); for (int j = 0;
     * j < inclusions.length; j++) { T_test_label_inclusion inclusion =
     * inclusions[j]; LabelTreeNode childNode = (LabelTreeNode)
     * labelNodeMap.get(inclusion.getContainee().getId()); if (childNode !=
     * null) { node.addChild(childNode); } } }
     * 
     * if (label.t_test_label_inclusion1.size() == 0) { root.addChild(node); } }
     * return root; }
     */
    public int getNumberOfLabelPairs(int labelId) {
	int result = 0;
	try {
	    PersistentTransaction t = openDBConnection().beginTransaction();
	    try {
		T_test_labelpairsCriteria pairCriteria = new T_test_labelpairsCriteria();
		pairCriteria.labelId.eq(labelId);
		T_test_labelpairs[] pairs = pairCriteria
			.listT_test_labelpairs();
		result = pairs.length;
	    } catch (PersistentException ex) {
	    } finally {
		closeDBConnection();
	    }
	} catch (PersistentException ex) {
	}
	return result;
    }

    public T_test_label getLabelById(int labelId) {
	if (m_labels.containsKey(labelId)) {
	    return m_labels.get(labelId);
	}
	T_test_label result = null;
	try {
	    T_test_labelCriteria criteria = new T_test_labelCriteria();
	    criteria.id.eq(labelId);
	    result = criteria.uniqueT_test_label();
	    m_labels.put(labelId, result);
	} catch (PersistentException ex) {
	}
	return result;
    }

    public T_test_label getLabelByName(String name) {
	T_test_label result = null;
	T_test_labelCriteria criteria;
	try {
	    criteria = new T_test_labelCriteria();
	    criteria.name.eq(name);
	    result = criteria.uniqueT_test_label();
	} catch (PersistentException ex) {
	}
	return result;
    }

    public int saveLabel(String name) {
	int result = 0;
	try {
	    PersistentTransaction t = openDBConnection().beginTransaction();
	    try {
		T_test_label obj = new T_test_label();
		obj.setName(name);
		obj.save();
		t.commit();
		result = obj.getId();
	    } catch (PersistentException ex) {
		t.rollback();
	    } finally {
		closeDBConnection();
	    }
	} catch (PersistentException ex) {
	}
	return result;
    }

    public boolean saveLabel(int id, String name) {
	boolean result = false;
	try {
	    PersistentTransaction t = openDBConnection().beginTransaction();
	    try {
		T_test_labelCriteria criteria = new T_test_labelCriteria();
		T_test_label obj = null;
		if (id != 0) {
		    criteria.id.eq(id);
		    obj = criteria.uniqueT_test_label();
		}

		if (obj == null) {
		    obj = new T_test_label();
		}

		obj.setName(name);
		obj.save();
		t.commit();
		result = true;
	    } catch (PersistentException ex) {
		t.rollback();
	    } finally {
		closeDBConnection();
	    }
	} catch (PersistentException ex) {
	}
	return result;
    }

    public boolean saveLabel(int id, String name, int containerId) {
	boolean result = false;
	try {
	    PersistentTransaction t = openDBConnection().beginTransaction();
	    try {
		T_test_labelCriteria criteria = new T_test_labelCriteria();
		T_test_label obj = null;
		if (id != 0) {
		    criteria.id.eq(id);
		    obj = criteria.uniqueT_test_label();
		}
		if (obj == null) {
		    obj = new T_test_label();
		}
		obj.setName(name);
		obj.save();
		t.commit();
		result = true;
	    } catch (PersistentException ex) {
		t.rollback();
	    } finally {
		closeDBConnection();
	    }

	} catch (PersistentException ex) {
	}
	return result;
    }

    public int addLabel(String name, int containerId) {
	int result = 0;
	try {
	    PersistentTransaction t = openDBConnection().beginTransaction();
	    try {
		T_test_label containee = new T_test_label();
		containee.setName(name);
		containee.save();
		T_test_label container = getLabelById(containerId);
		if (container != null) {
		    T_test_label_inclusion inclusion = new T_test_label_inclusion();
		    inclusion.setContainee(containee);
		    inclusion.setContainer(container);
		    inclusion.save();
		}
		t.commit();
		m_labels.put(containee.getId(), containee);
		result = containee.getId();
	    } catch (PersistentException ex) {
		t.rollback();
	    } finally {
		closeDBConnection();
	    }
	} catch (PersistentException ex) {
	}
	return result;
    }

    public HashMap getLabelsForTestCase(int testCaseId) {
	HashMap result = new HashMap();
	try {
	    T_test_labelpairsCriteria criteria = new T_test_labelpairsCriteria();
	    criteria.createTestCaseCriteria().id.eq(testCaseId);
	    T_test_labelpairs[] pairs = criteria.listT_test_labelpairs();
	    for (int i = 0; i < pairs.length; i++) {
		result.put(pairs[i].getId(), pairs);
	    }
	} catch (PersistentException ex) {
	}
	return result;
    }

    public HashMap getLabelsForTestCaseGroup(int testCaseGroupId) {
	return getLabelsForTestCase(testCaseGroupId);
    }

    public HashMap getLabelsForTestStepGroup(int testStepGroupId) {
	return getLabelsForTestCase(testStepGroupId);
    }

    public HashMap getLabelsForTestStep(int testStepId) {
	HashMap result = new HashMap();
	try {
	    T_test_labelpairsCriteria criteria = new T_test_labelpairsCriteria();
	    criteria.createTestStepCriteria().id.eq(testStepId);
	    T_test_labelpairs[] pairs = criteria.listT_test_labelpairs();
	    for (int i = 0; i < pairs.length; i++) {
		result.put(pairs[i].getId(), pairs);
	    }
	} catch (PersistentException ex) {
	}
	return result;
    }

    public HashMap getLabelsForDataObject(int dataObjectId) {
	HashMap result = new HashMap();
	try {
	    T_test_labelpairsCriteria criteria = new T_test_labelpairsCriteria();
	    criteria.createDataObjectCriteria().id.eq(dataObjectId);
	    T_test_labelpairs[] pairs = criteria.listT_test_labelpairs();
	    for (int i = 0; i < pairs.length; i++) {
		result.put(pairs[i].getId(), pairs);
	    }
	} catch (PersistentException ex) {
	}
	return result;
    }

    public static void main(String args[]) {
	DefaultLabelTreeDataHandler handler = new DefaultLabelTreeDataHandler();
	LabelTreeNode labelTree = handler.getLabelTree();
	// handler.removeLabel(2);

	/*
	 * LabelDataHandler ldHandler = new LabelDataHandler(); HashMap
	 * labelDataMap = ldHandler.getLabelDataListAsMap(); LabelTreeNode root
	 * = ldHandler.convertToLabelTreeNode(labelDataMap);
	 */

	/*
	 * LabelDataHandler ldHandler = new LabelDataHandler(); HashMap
	 * labelDataMap = ldHandler.getLabelDataListAsMap();
	 * System.out.println("HashMap contains " + labelDataMap.size() +
	 * " key value pair.");
	 * System.out.println("Retriving all keys from the HashMap"); Iterator
	 * iterator = labelDataMap.keySet().iterator(); while
	 * (iterator.hasNext()) { LabelData ld = (LabelData)
	 * labelDataMap.get(iterator.next()); StringBuilder sb = new
	 * StringBuilder(ld.getName()); if (ld.getParent() != null) {
	 * sb.append(" is child of " + ld.getParent().getName()); }
	 * System.out.println(sb.toString()); }
	 */
    }
}
